package com.apes.framework.plugin.outbox;

import com.apes.framework.jpa.repository.CustomRepository;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;

import java.util.Date;
import java.util.List;
import java.util.Map;

public interface OutboxEventRepository extends CustomRepository<OutboxEvent, String> {

    List<OutboxEvent> findByCreateDateGreaterThanAndTimestampLessThanEqualAndTimesAndHandledOrderByCreateDateAsc(Date createDate, Long maxTimestamp, int times, int handled, Pageable pageable);

    List<OutboxEvent> findByCreateDateGreaterThanAndUpdateDateLessThanAndTimesLessThanOrderByCreateDateAsc(Date createDate, Date updateDate, int times, Pageable pageable);

    int countAllBySubscriberAndAggregateTypeAndAggregateIdAndIdLessThan(String subscriber, String aggregateType, String aggregateId, String id);

    List<OutboxEvent> findBySubscriberOrderByCreateDateAsc(String subscriber);


    List<OutboxEvent> findBySubscriberAndCreateDateGreaterThanAndTimestampLessThanEqualOrderByIdAsc(String subscriber, Date createDate, Long maxTimestamp, Pageable pageable);

    @Query(value = "SELECT * FROM OUTBOX_EVENT T WHERE AGGREGATE_ID LIKE '%' || ?1 || '%' AND OUTBOX_SUBSCRIBER_ID = ?2 AND NOT EXISTS (SELECT 1 FROM OUTBOX_EVENT_BACKUP J WHERE J.OUTBOX_EVENT_ID = T.ID) ORDER BY ID ", nativeQuery = true)
    List<OutboxEvent> accordingAggregateIdQuery(String aggregateId, String outboxSubscriberId);

    @Query(value = "SELECT * FROM OUTBOX_EVENT T WHERE AGGREGATE_ID LIKE '%' || ?1 || '%' AND NOT EXISTS (SELECT 1 FROM OUTBOX_EVENT_BACKUP J WHERE J.OUTBOX_EVENT_ID = T.ID) ORDER BY ID ", nativeQuery = true)
    List<OutboxEvent> accordingAggregateIdQuery(String aggregateId);


    @Query(value = "SELECT * FROM OUTBOX_EVENT T WHERE AGGREGATE_ID LIKE '%' || ?1 || '%' AND OUTBOX_SUBSCRIBER_ID = ?2 AND EXISTS (SELECT 1 FROM OUTBOX_EVENT_BACKUP J WHERE J.OUTBOX_EVENT_ID = T.ID) ORDER BY ID ", nativeQuery = true)
    List<OutboxEvent> existsEventBack(String aggregateId, String outboxSubscriberId);


    @Query(value = "SELECT DISTINCT AGGREGATE_ID FROM OUTBOX_EVENT T WHERE AGGREGATE_ID LIKE '%' || ?1 || '%' AND OUTBOX_SUBSCRIBER_ID = ?2 AND ROWNUM = 1 ", nativeQuery = true)
    Map accordAggregateIdQ(String aggregateId, String outboxSubscriberId);
}
